home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / citsrc6K05.lha / callstat.c < prev    next >
C/C++ Source or Header  |  1996-10-13  |  27KB  |  697 lines

  1.  
  2. /*
  3.    Hue: This is the source of the current version of callstat.  I've been
  4.         running it on my system for some time, and it seems to be stable.
  5.         Unfortunately, one of the other Swarm Sysops, who has a hard-drive-
  6.         based STadel node, has reported that this version of callstat acts
  7.         very strangely with his system.  I haven't yet figured where the
  8.         problem is...
  9.         In any case, the basic logic is sound, and fairly straightforward.
  10.         The program is undocumented as yet; I haven't reached the point
  11.         where I'm ready to release it to the public, and I never document
  12.         my own code...until it's too late.  :-)  Anyway, I don't expect
  13.         you'll have much trouble figuring things out.  The only problem
  14.         areas are in the Cit-specific stuff, such as access to ctdltabl.sys
  15.         and calllog.sys.
  16.         Any comments, questions, complaints, or speeches would be welcomed,
  17.         unless they deal with my personal programming style.  :-)
  18.  
  19.         --Royce, 13Mar88, far too late in the evening...
  20. */
  21.  
  22. #define BOOLEAN int
  23.  
  24. #define CITADEL86       1
  25. /* #define ATARI_ST        1 */
  26. #include "ctdl.h"    /* header file  */
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <math.h>
  31. #include <ctype.h>
  32. #include <time.h>
  33. #include <proto/exec.h>
  34. #include <dos/dos.h>
  35. #include <pragmas/dos_pragmas.h>
  36. #include "exec/memory.h"
  37. #include "exec/ports.h"
  38. #include "exec/exec.h"
  39.  
  40.  
  41. #ifdef ATARI_ST
  42.  
  43. #include <osbind.h>
  44. #include "audit.h"
  45.  
  46. extern struct config    cfg;
  47.  
  48. #endif
  49.  
  50. #ifdef CITADEL86
  51.  
  52. #define safeopen        fopen
  53. #define Cconin()        getchar()
  54. #define Fdelete         unlink
  55. #define doExit          exit
  56.  
  57. typedef char pathSpec[200];
  58.  
  59. extern CONFIG           cfg;
  60.  
  61. void get_data(void);
  62. void munch(void);
  63. void write_data(void);
  64. void write_stat_file(void);
  65. void UpdateBar(void);
  66. long baud_code(long baud);
  67. void file_error(char *file, char *access);
  68. BOOLEAN find_on(void);
  69. char get_stuff(void);
  70. void write_a_stat(char *desc, char stat);
  71. void write_hist_bar(unsigned stat, float factor);
  72.  
  73. #endif
  74.  
  75. struct {
  76.         unsigned hour,min;
  77. } on,off,last;
  78.  
  79. BOOLEAN newuser,termstay,disconnect,preempt,timeout,evile,nosysop,update,docb,
  80. debug, barupdate, SysUp = FALSE;
  81. char    ch,date[20],str[20];
  82. long baud;
  83. unsigned long dur;
  84. FILE    *safeopen(),*fp;
  85. pathSpec fnlog = "",fndat,fnstat,fncallbaud;
  86.  
  87. long total,calls[24],durations[20],callbaud[24][9],
  88.         nnewusers,ntermstays,ndisconnects,nnewdiscons,npreempts,
  89.         ntimeouts,neviles;
  90. long bauds[9] = { 0, 0, 0,  0, 0, 0,  0, 0, 0 };
  91. long    totalduration,totalidle, netcount;
  92.  
  93. long    baudduration[9] = { 0l, 0l, 0l,  0l, 0l, 0l,  0l, 0l, 0l};
  94. char    bartitle[100] = "";
  95.  
  96. int main(int , char **);
  97.  
  98. int main(argc,argv)
  99. int     argc;
  100. char    *argv[];
  101. {
  102.         cfg.weAre = UTILITY;
  103.         printf("Citadel Caller Log Statistics Report, %s\n", VERSION_NAME);
  104.         printf("Do a 'callstat -?' for help.\n");
  105.         nosysop = FALSE;
  106.         update = FALSE;
  107.         docb = FALSE;
  108.         debug = FALSE;
  109.         while (argc > 1) {
  110.                 --argc;
  111.                 ++argv;
  112. #ifndef CITADEL86
  113.                 if (strcmp(*argv, "-c") == 0)
  114.                         docb = TRUE;
  115.                 if (strcmp(*argv, "-d") == 0)
  116.                         debug = TRUE;
  117.                 if (strcmp(*argv, "-s") == 0)
  118.                         nosysop = TRUE;
  119.                 if (strcmp(*argv, "-u") == 0)
  120.                         update = TRUE;
  121.                 if (strcmp(*argv, "-?") == 0) {
  122.                         printf("usage: callstat [-c] [-s] [-u]\n");
  123.                         printf("       -c writes callbaud.sys\n");
  124.                         printf("       -s turns off sysConsole stats\n");
  125.                         printf("       -u deletes calllog.sys & updates calldata.sys\n");
  126.                         doExit(0);
  127.                 }
  128. #else
  129.                 if (strcmp(*argv, "-c") == 0)
  130.                         docb = TRUE;
  131.                 else if (strcmp(*argv, "-d") == 0)
  132.                         debug = TRUE;
  133.                 else if (strcmp(*argv, "-s") == 0)
  134.                         nosysop = TRUE;
  135.                 else if (strcmp(*argv, "-u") == 0)
  136.                         update = TRUE;
  137.                 else if (strncmp(*argv, "-b", 2) == 0) {
  138.                         barupdate = TRUE;
  139.                         if (strlen(*argv) > 2)
  140.                                 strcpy(bartitle, *argv + 2);
  141.                 }
  142.                 else if (strcmp(*argv, "-?") == 0) {
  143.                         printf("usage: callstat [-c] [-s] [-u] [filename]\n");
  144.                         printf("       -c writes callbaud.sys\n");
  145.                         printf("       -s turns off sysConsole stats\n");
  146.                         printf("       -u deletes calllog.sys & updates calldata.sys\n");
  147.                         printf("       -b[title name] updates bar.sys\n");
  148.                         printf("       \"filename\" analyze this file, instead\n");
  149.                         doExit(0);
  150.                 }
  151.                 else if (**argv != '-') {
  152.                     strcpy(fnlog, *argv);
  153.                 }
  154. #endif
  155.         }
  156. #ifdef ATARI_ST
  157.         if (!readSysTab(FALSE))
  158. #endif
  159. #ifdef CITADEL86
  160.         if (!readSysTab(FALSE, TRUE))
  161. #endif
  162.                 doExit(1);
  163. #ifdef ATARI_ST
  164.         if (((cfg.call_log & aEXIT) == 0) || ((cfg.call_log & aLOGIN) == 0) ||
  165.                 ((cfg.call_log & aDNLOAD == 1))) {
  166.                 printf("Sorry, but callstat currently needs system ups & downs\n");
  167.                 printf("and user logins to be recorded, and file transfers to\n");
  168.                 printf("be unrecorded.\n");
  169.                 doExit(1);
  170.         }
  171. #endif
  172.  
  173. #ifdef ATARI_ST
  174.         if (strlen(fnlog) == 0)
  175.             sprintf(fnlog,"%s\\CALLLOG.SYS",&cfg.codeBuf[cfg.auditDir]);
  176.         sprintf(fndat,"%s\\CALLDATA.SYS",&cfg.codeBuf[cfg.sysDir]);
  177.         sprintf(fnstat,"%s\\CALLSTAT.SYS",&cfg.codeBuf[cfg.auditDir]);
  178.         sprintf(fncallbaud,"%s\\CALLBAUD.SYS",&cfg.codeBuf[cfg.auditDir]);
  179. #endif
  180. #ifdef CITADEL86
  181.         if (strlen(fnlog) == 0)
  182.             makeSysName(fnlog, "calllog.sys", &cfg.auditArea);
  183.         makeSysName(fndat, "calldata.sys", &cfg.auditArea);
  184.         makeSysName(fnstat, "callstat.sys", &cfg.auditArea);
  185.         makeSysName(fncallbaud, "callbaud.sys", &cfg.auditArea);
  186. #endif
  187.         last.hour = 100;
  188.         get_data();
  189.         munch();
  190.         if (update) {
  191.                 Fdelete(fnlog);
  192.                 write_data();
  193.         }
  194. #ifdef CITADEL86
  195.         if (barupdate) {
  196.                 UpdateBar();
  197.         }
  198. #endif
  199.         write_stat_file();
  200.   return 0;
  201. }
  202.  
  203. void file_error(char *file, char *access)
  204. {
  205.         printf("Can't open %s for %s!\n",file,access);
  206.         printf("Hit return: "); /* For people running under GEM desktop. */
  207.         ch = Cconin();
  208.         printf("\n");
  209. }
  210.  
  211. void get_data()
  212. {
  213.         unsigned        i,j;
  214.  
  215.         if ((fp = safeopen(fndat,"r")) == NULL) {
  216.                 date[0] = NULL;
  217.                 total = 0;
  218.                 zero_struct(calls);
  219.                 zero_struct(durations);
  220.                 totalduration = 0;
  221.                 totalidle = 0;
  222.                 zero_struct(bauds);
  223.                 zero_struct(callbaud);
  224.                 nnewusers = 0;
  225.                 ntermstays = 0;
  226.                 ndisconnects = 0;
  227.                 nnewdiscons = 0;
  228.                 npreempts = 0;
  229.                 ntimeouts = 0;
  230.                 neviles = 0;
  231.         }
  232.         else {
  233.                 printf("Reading cumulative data...\n");
  234.                 fscanf(fp,"%s\n",date);
  235.                 fscanf(fp,"%d\n",&total);
  236.                 for (i = 0; i <= 23; i++)
  237.                         fscanf(fp,"%d\n",&calls[i]);
  238.                 for (i = 0; i <= 19; i++)
  239.                         fscanf(fp,"%d\n",&durations[i]);
  240.                 fscanf(fp,"%ld\n",&totalduration);
  241.                 fscanf(fp,"%ld\n",&totalidle);
  242.                 for (i = 0; i <= 8; i++)
  243.                         fscanf(fp,"%d\n",&bauds[i]);
  244.                 for (i = 0; i <= 23; i++)
  245.                         for (j = 0; j <= 8; j++)
  246.                                 fscanf(fp,"%d\n",&callbaud[i][j]);
  247.                 fscanf(fp,"%d\n",&nnewusers);
  248.                 fscanf(fp,"%d\n",&ntermstays);
  249.                 fscanf(fp,"%d\n",&ndisconnects);
  250.                 fscanf(fp,"%d\n",&nnewdiscons);
  251.                 fscanf(fp,"%d\n",&npreempts);
  252.                 fscanf(fp,"%d\n",&ntimeouts);
  253.                 fscanf(fp,"%d\n",&neviles);
  254.                 fclose(fp);
  255.         }
  256. }
  257.  
  258. long baud_code(long baud)
  259. {
  260.         if (baud == 300)            return 1;
  261.         else if (baud == 1200)      return 2;
  262.         else if (baud == 2400)      return 3;
  263.         else if (baud == 4800)      return 4;
  264.         else if (baud == 9600)      return 5;
  265.         else if (baud == 14400)     return 6;
  266.         else if (baud == 19200)     return 7;
  267.         else if (baud >= 38400)     return 8;
  268.         else  return 0;
  269. }
  270.  
  271. char isnet;
  272. BOOLEAN find_on()       /* Scan for next user login time. */
  273. {
  274.         int     rc;
  275.         char    up, buffer[800];
  276.  
  277.         buffer[0] = 0;
  278.         do {
  279.                 str[0] = NULL;
  280.                 rc = fscanf(fp,"%s ",str);
  281.                 if (debug)
  282.                         printf("-%s-",str);
  283.  
  284.                 if (strcmp(str, "up") == 0)
  285.                         up = TRUE;
  286.  
  287.                 /* Next if handles system down/up. */
  288.                 strcat(buffer, str);
  289.                 if ((rc == 1) && (str[0] == '@')) {
  290.                         if (debug)
  291.                                 printf("\n");
  292.                         if (last.hour != 100) {
  293.                                 if (SysUp && up) {      /* damaged calllog */
  294.                                         fscanf(fp,"%d:",&last.hour);
  295.                                         fscanf(fp,"%d\n",&last.min);
  296.                                         on.hour = 100;
  297.                                 }
  298.                                 else {
  299.                                         fscanf(fp,"%d:",&on.hour);
  300.                                         fscanf(fp,"%d\n",&on.min);
  301.                                 }
  302.                         }
  303.                         else {
  304.                                 fscanf(fp,"%d:",&last.hour);
  305.                                 fscanf(fp,"%d\n",&last.min);
  306.                                 on.hour = 100;
  307.                         }
  308.                         if (on.hour != 100) {
  309.                                 if (last.hour > on.hour)
  310.                                         on.hour += 24;
  311.                                 dur = ((on.hour * 60 + on.min) -
  312.                                         (last.hour * 60 + last.min));
  313. /*printf("\n1: adding %d\n", dur);*/
  314.                                 totalidle += dur;
  315.                                 last.hour = 100;
  316.                         }
  317.                         up = FALSE;
  318.                 }
  319.         } while (strcmp(str, "mode:") && (rc != EOF) && ((str[0] != ':') || (str[1] != NULL)));
  320.         if (debug)
  321.                 printf("buffer is -%s-", buffer);
  322.         /*
  323.            Bug: Normally, the only time the substring " : " shows up in the
  324.                 calllog, is between a userID and the date of the login.  Thus
  325.                 the previous while loop scans for words (i.e. a sequence of
  326.                 characters terminated by white-space), and terminates when it
  327.                 finds the word ": ".  Normally, this means that the date and
  328.                 time of signon are to immediately follow.
  329.                 However, if some userID contains the substring " : " (or ": "
  330.                 at the start), callstat will rapidly go to heg.  More
  331.                 stringent error-checking is needed to guard against this
  332.                 (e.g., check to make sure that something of the form ddCccdd
  333.                 follows the current instance of ": ", where d is a digit and
  334.                 C/c is a character)...
  335.         */
  336.         if (debug)
  337.                 printf("\n");
  338.         if (rc == EOF)
  339.                 return FALSE;
  340.         else {
  341.                 SysUp = TRUE;
  342.                 fscanf(fp,"%s ",str);   /* Skip the date */
  343.                 if (date[0] == NULL)    /* Record it if needed (first time) */
  344.                         strcpy(date,str);
  345.                 isnet = (strcmp(buffer, "Systeminnetworkmode:") == 0);
  346.                 return TRUE;
  347.         }
  348. }
  349.  
  350. char get_stuff()
  351. {
  352.         int     rc;
  353.  
  354.         fscanf(fp,"%d:",&on.hour);
  355.         fscanf(fp,"%d - ",&on.min);
  356.         rc = fscanf(fp,"%d:",&off.hour);
  357.         if (rc != 1) {
  358.                 printf("\nYuck!  Your calllog.sys file is corrupted!\n");
  359.                 printf("(A user is recorded as logging in, but not out.)\n");
  360.                 printf("Please use an editor to fix things before rerunning.\n");
  361.                 fclose(fp);
  362.                 doExit(1);
  363.         }
  364.         fscanf(fp, (isnet) ? "%d" : "%d (", &off.min);
  365.         if (!isnet) {
  366.                 rc = fscanf(fp,"%d)",&baud);
  367.                 if (rc == 0) {                  /* Login was at sysConsole */
  368.                         baud = 0;
  369.                         fscanf(fp,"%s)",str);
  370.                 }
  371.                 baud = baud_code(baud);
  372.         }
  373.         else baud = 0;
  374.         newuser = FALSE;
  375.         termstay = FALSE;
  376.         disconnect = FALSE;
  377.         preempt = FALSE;
  378.         timeout = FALSE;
  379.         evile = FALSE;
  380.         do {
  381.                 ch = getc(fp);
  382.                 switch (ch) {
  383.                         case '+' :
  384.                                 newuser = TRUE;
  385.                                 break;
  386.                         case '-' :
  387.                                 termstay = TRUE;
  388.                                 break;
  389.                         case 'd' :
  390.                                 disconnect = TRUE;
  391.                                 break;
  392.                         case 'p' :
  393.                                 preempt = TRUE;
  394.                                 break;
  395.                         case 't' :
  396.                                 timeout = TRUE;
  397.                                 break;
  398.                         case 'E' :
  399.                                 evile = TRUE;
  400.                         default :
  401.                                 break;
  402.                 }
  403.         } while (ch != '\n');
  404.         return isnet;
  405. }
  406.  
  407. void munch()
  408. {
  409.         char net;
  410.  
  411.         if ((fp = safeopen(fnlog,"r")) == NULL) {
  412.                 file_error("calllog.sys","input");
  413.                 return;
  414.         }
  415.         printf("Munching...\n");
  416.         while (find_on()) {
  417.                 net = get_stuff();
  418.                 if (!net) total++;
  419.                 printf("\r%d",total);
  420.                 if (!net) calls[on.hour]++;
  421.                 if (last.hour > on.hour)
  422.                         on.hour += 24;
  423.                 dur=((on.hour*60+on.min)-(last.hour*60+last.min));
  424. /*printf("\n2: adding %ld (Last was %d:%02d, now is %d:%02d)\n", dur, last.hour, last.min, on.hour, on.min);*/
  425.                 totalidle += dur;
  426.                 if (on.hour >= 24)
  427.                         on.hour -= 24;
  428.                 last.hour = off.hour;
  429.                 last.min = off.min;
  430.                 if (on.hour > off.hour)
  431.                         off.hour += 24;
  432.                 dur=((off.hour*60+off.min) - (on.hour * 60 + on.min));
  433.                 if (!net) {
  434.                         totalduration += dur;
  435.                         baudduration[baud] += dur;
  436.                 }
  437.                 else netcount++;
  438.                 dur /= 15;
  439.                 if (dur > 19)
  440.                         dur = 19;
  441.                 if (!net) {
  442.                         durations[dur]++;
  443.                         bauds[baud]++;
  444.                         callbaud[on.hour][baud]++;
  445.                         if (newuser)
  446.                                 nnewusers++;
  447.                         if (termstay)
  448.                                 ntermstays++;
  449.                         if (disconnect) {
  450.                                 ndisconnects++;
  451.                                 if (newuser)
  452.                                         nnewdiscons++;
  453.                         }
  454.                         if (preempt)
  455.                                 npreempts++;
  456.                         if (timeout)
  457.                                 ntimeouts++;
  458.                         if (evile)
  459.                                 neviles++;
  460.                 }
  461.         }
  462.         fclose(fp);
  463.         printf("\n");
  464. }
  465.  
  466. void write_data()
  467. {
  468.         unsigned        i,j;
  469.  
  470.         if ((fp = safeopen(fndat,"w")) == NULL)
  471.                 file_error("calldata.sys","output");
  472.         else {
  473.                 printf("Writing cumulative data...\n");
  474.                 fprintf(fp,"%s\n",date);
  475.                 fprintf(fp,"%d\n",total);
  476.                 for (i = 0; i <= 23; i++)
  477.                         fprintf(fp,"%d\n",calls[i]);
  478.                 for (i = 0; i <= 19; i++)
  479.                         fprintf(fp,"%d\n",durations[i]);
  480.                 fprintf(fp,"%ld\n",totalduration);
  481.                 fprintf(fp,"%ld\n",totalidle);
  482.                 for (i = 0; i <= 8; i++)
  483.                         fprintf(fp,"%d\n",bauds[i]);
  484.                 for (i = 0; i <= 23; i++)
  485.                         for (j = 0; j <= 8; j++)
  486.                                 fprintf(fp,"%d\n",callbaud[i][j]);
  487.                 fprintf(fp,"%d\n",nnewusers);
  488.                 fprintf(fp,"%d\n",ntermstays);
  489.                 fprintf(fp,"%d\n",ndisconnects);
  490.                 fprintf(fp,"%d\n",nnewdiscons);
  491.                 fprintf(fp,"%d\n",npreempts);
  492.                 fprintf(fp,"%d\n",ntimeouts);
  493.                 fprintf(fp,"%d\n",neviles);
  494.                 fclose(fp);
  495.         }
  496. }
  497.  
  498. void write_hist_bar(unsigned stat, float factor)
  499. {
  500.         unsigned        i;
  501.  
  502.         fprintf(fp,": ");
  503.         if ((stat / factor) >= 1.0)
  504.                 for (i = 1; i <= (int) (stat / factor); i++)
  505.                         fprintf(fp,"*");
  506.         else if (stat >= 1)
  507.                 fprintf(fp,"*");
  508.         fprintf(fp," (%d)\n", stat);
  509.         fflush(fp);
  510. }
  511.  
  512. void write_a_stat(char *desc, char stat)
  513. {
  514. #ifndef CITADEL86
  515.         fprintf(fp,"%s: %d (%d%%)\n",desc,stat,stat * 100 / total);
  516. #else
  517.         fprintf(fp, "%-30s%-15d%d\n", desc, stat, stat * 100 / total);
  518. #endif
  519. }
  520.  
  521. void write_stat_file()
  522. {
  523.         unsigned        i,j,max;
  524.         float           factor;
  525.  
  526.         Fdelete(fnstat);
  527.         if ((fp = safeopen(fnstat,"w")) == NULL)
  528.                 file_error("callstat.sys","output");
  529.         else {
  530.                 printf("Writing stat file...\n");
  531.                 fprintf(fp,"\n The Antithesystem Memorial RT Histogram.\n\n");
  532.                 fprintf(fp," The following statistics have been collected since %s.\n\n",date);
  533.                 fprintf(fp," Total number of calls represented: %d\n\n",total);
  534.                 max = 25;
  535.                 for (i = 0; i <= 23; i++)
  536.                         if (calls[i] > max)
  537.                                 max = calls[i];
  538.                 factor = max / 25.0;
  539.                 fprintf(fp," Usage histogram (each number represents an hour of the day, each '*'\n");
  540.                 fprintf(fp,"represents about %d calls at that hour):\n",(int) factor);
  541.                 for (i = 0; i <= 23; i++) {
  542.                         fprintf(fp,"%3d",i);
  543.                         write_hist_bar(calls[i],factor);
  544.                 }
  545.                 fprintf(fp,"\n");
  546.                 max = 25;
  547.                 for (i = 0; i <= 19; i++)
  548.                         if (durations[i] > max)
  549.                                 max = durations[i];
  550.                 factor = max / 25.0;
  551.                 fprintf(fp," Call duration histogram (each number represents a call duration of at\n");
  552.                 fprintf(fp,"most that much time, each '*' represents about %d calls of that duration):\n",(int) factor);
  553.                 for (i = 0; i <= 19; i++) {
  554.                         fprintf(fp,"%2d:%d",(i + 1) * 15 / 60,(i + 1) * 15 % 60);
  555.                         if (i % 4 == 3)
  556.                                 fprintf(fp,"0");
  557.                         write_hist_bar(durations[i],factor);
  558.                 }
  559.                 fprintf(fp," The average call duration is about %ld minutes.\n",totalduration / total);
  560.                 fprintf(fp," The average idle time before/after a call is about %ld minutes.\n\n",totalidle / total);
  561.                 max = 25;
  562.                 for (i = 0; i <= 8; i++)
  563.                         if (bauds[i] > max)
  564.                                 max = bauds[i];
  565.                 factor = max / 25.0;
  566.                 fprintf(fp," Baud rate histogram (each number represents a baud rate, each '*' represents\n");
  567.                 fprintf(fp,"about %d calls at that baud rate):\n",(int) factor);
  568.                 for (i = 0 + nosysop; i <= cfg.sysBaud + 1; i++) {
  569.                         switch (i) {
  570.                                 case 0 :  fprintf(fp,"  sys");  break;
  571.                                 case 1 :  fprintf(fp,"  300");  break;
  572.                                 case 2 :  fprintf(fp," 1200");  break;
  573.                                 case 3 :  fprintf(fp," 2400");  break;
  574.                                 case 4 :  fprintf(fp," 4800");  break;
  575.                                 case 5 :  fprintf(fp," 9600");  break;
  576.                                 case 6 :  fprintf(fp,"14400");  break;
  577.                                 case 7 :  fprintf(fp,"19200");  break;
  578.                                 case 8 :  fprintf(fp,"38400");  break;
  579.                         }
  580.                         write_hist_bar(bauds[i],factor);
  581.                 }
  582.                 fprintf(fp,"\n");
  583.                 fprintf(fp, "There were %ld network sessions.\n\n", netcount);
  584. #ifndef CITADEL86
  585.                 write_a_stat(" Number of new users",nnewusers);
  586.                 write_a_stat(" Number of uses of .T(erminate) S(tay)",ntermstays);
  587.                 write_a_stat(" Number of disconnects",ndisconnects);
  588.                 write_a_stat(" Number of new user disconnects",nnewdiscons);
  589.                 write_a_stat(" Number of preemptions",npreempts);
  590.                 write_a_stat(" Number of time-outs",ntimeouts);
  591.                 write_a_stat(" Number of EVILE users",neviles);
  592. #else
  593.                 fprintf(fp, "%-25s%-15s%s\n", " Description",
  594.                         "Total Number", "Percentage");
  595.                 fprintf(fp, "%-25s%-15s%s\n", " -----------",
  596.                         "------------", "----------");
  597.                 write_a_stat(" New users", nnewusers);
  598.                 write_a_stat(" .T(erminate) S(tay) usage", ntermstays);
  599.                 write_a_stat(" Disconnects", ndisconnects);
  600.                 write_a_stat(" New user disconnects", nnewdiscons);
  601.                 write_a_stat(" Preemptions", npreempts);
  602.                 write_a_stat(" Time-outs", ntimeouts);
  603.                 write_a_stat(" EVILE users", neviles);
  604. #endif
  605.                 fclose(fp);
  606.         }
  607.         if (docb != TRUE)
  608.                 return;
  609.         Fdelete(fncallbaud);
  610.         if ((fp = safeopen(fncallbaud,"w")) == NULL)
  611.                 file_error("callbaud.sys","output");
  612.         else {
  613.                 printf("Writing call/baud file...\n");
  614.                 fprintf(fp,"\n");
  615.                 fprintf(fp," The following statistics have been collected since %s.\n\n",date);
  616.                 fprintf(fp," Total number of calls represented: %d\n\n",total);
  617.                 max = 25;
  618.                 for (i = 0; i <= 23; i++)
  619.                         for (j = 0; j <= 8; j++)
  620.                                 if (callbaud[i][j] > max)
  621.                                         max = callbaud[i][j];
  622.                 factor = max / 25.0;
  623.                 fprintf(fp," Usage/baud rate histogram (each pair of numbers represents an hour of the\n");
  624.                 fprintf(fp,"day and a baud rate, each '*' represents about %d calls at that hour and\n",(int) factor);
  625.                 fprintf(fp,"baud rate):\n");
  626.                 for (i = 0; i <= 23; i++)
  627.                         for (j = 0 + nosysop; j <= cfg.sysBaud + 1; j++) {
  628.                                 fprintf(fp,"%3d,",i);
  629.  
  630.                         switch (j) {
  631.                                 case 0 :  fprintf(fp,"  sys");  break;
  632.                                 case 1 :  fprintf(fp,"  300");  break;
  633.                                 case 2 :  fprintf(fp," 1200");  break;
  634.                                 case 3 :  fprintf(fp," 2400");  break;
  635.                                 case 4 :  fprintf(fp," 4800");  break;
  636.                                 case 5 :  fprintf(fp," 9600");  break;
  637.                                 case 6 :  fprintf(fp,"14400");  break;
  638.                                 case 7 :  fprintf(fp,"19200");  break;
  639.                                 case 8 :  fprintf(fp,"38400");  break;
  640.                         }
  641.                                 write_hist_bar(callbaud[i][j],factor);
  642.                         }
  643.                 fclose(fp);
  644.         }
  645. }
  646.  
  647. void crashout(str)
  648. char *str;
  649. {
  650.     puts(str);
  651.     doExit(1);
  652. }
  653.  
  654. /*
  655.  * Note Royce doesn't support 4800, so we must force in a 0.
  656.  */
  657. void UpdateBar()
  658. {
  659.         FILE *fd, *fopen();
  660.         extern char *APPEND_TEXT;
  661.  
  662.         if ((fd = fopen("bar.sys", APPEND_TEXT)) != NULL) {
  663.                 if (strlen(bartitle) == 0) {
  664.                         printf("Title for this data: ");
  665.                         gets(bartitle);
  666.                 }
  667.                 fprintf(fd, "%s\n", bartitle);
  668.                 fprintf(fd, "%d\n", bauds[0]);
  669.                 fprintf(fd, "%ld\n", baudduration[0]);
  670.                 fprintf(fd, "%d\n", bauds[1]);
  671.                 fprintf(fd, "%ld\n", baudduration[1]);
  672.                 fprintf(fd, "%d\n", bauds[2]);
  673.                 fprintf(fd, "%ld\n", baudduration[2]);
  674.                 fprintf(fd, "%d\n", bauds[3]);
  675.                 fprintf(fd, "%ld\n", baudduration[3]);
  676.                 fprintf(fd, "%d\n", bauds[4]);
  677.                 fprintf(fd, "%ld\n", baudduration[4]);
  678.                 fprintf(fd, "%d\n", bauds[5]);
  679.                 fprintf(fd, "%ld\n", baudduration[5]);
  680.                 fprintf(fd, "%d\n", bauds[6]);
  681.                 fprintf(fd, "%ld\n", baudduration[6]);
  682.                 fprintf(fd, "%d\n", bauds[7]);
  683.                 fprintf(fd, "%ld\n", baudduration[7]);
  684.                 fprintf(fd, "%d\n", bauds[8]);
  685.                 fprintf(fd, "%ld\n", baudduration[8]);
  686.                 fprintf(fd, "%d\n", 0);
  687.                 fprintf(fd, "0\n");
  688.                 fprintf(fd, "%d\n", bauds[8]);
  689.                 fprintf(fd, "%ld\n", baudduration[8]);
  690.                 fprintf(fd, "%ld\n", totalduration);
  691.                 fprintf(fd, "%ld\n", totalidle);
  692.                 fprintf(fd, "%d\n", nnewusers);
  693.                 fprintf(fd, "\n");
  694.                 fclose(fd);
  695.         }
  696. }
  697.